﻿using Newtonsoft.Json;
using System.Configuration;
using System.IO;
using System.Security.Cryptography;

namespace Super.Admin.Utils
{
    public class JsonHelper
    {
        // AES 加密配置
        private static readonly byte[] Key = Convert.FromBase64String(ConfigurationManager.AppSettings["EncryptionKey"]);      // Encoding.UTF8.GetBytes("SUPER-ADMIN-YYDS"); // 16/24/32 字节
        private static readonly byte[] IV = Convert.FromBase64String(ConfigurationManager.AppSettings["IV"]);      //Encoding.UTF8.GetBytes("SUPER-ADMIN-YYDS");   // 16 字节
        /// <summary>
        /// 将对象序列化为 JSON 并加密存储到文件（自定义后缀名）
        /// </summary>
        public static void SaveEncryptedJson<T>(T data, string filePath)
        {
            string json = JsonConvert.SerializeObject(data);
            string encryptedJson = AesEncrypt(json);
            File.WriteAllText(filePath, encryptedJson);
        }
        /// <summary>
        /// 从加密文件读取并解密为对象
        /// </summary>
        public static T LoadEncryptedJson<T>(string filePath)
        {
            string encryptedJson = File.ReadAllText(filePath);
            string json = AesDecrypt(encryptedJson);
            return JsonConvert.DeserializeObject<T>(json);
        }
        /// <summary>
        /// AES 加密字符串
        /// </summary>
        public static string AesEncrypt(string plainText)
        {
            using (Aes aes = Aes.Create())
            {
                aes.Key = Key;
                aes.IV = IV;
                // 创建加密器
                ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
                // 加密
                using (MemoryStream ms = new MemoryStream())
                {
                    using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
                    {
                        using (StreamWriter sw = new StreamWriter(cs))
                        {
                            sw.Write(plainText);
                        }
                        return Convert.ToBase64String(ms.ToArray()); // 返回 Base64 字符串
                    }
                }
            }
        }
        /// <summary>
        /// AES 解密字符串
        /// </summary>
        public static string AesDecrypt(string cipherText)
        {
            using (Aes aes = Aes.Create())
            {
                aes.Key = Key;
                aes.IV = IV;
                // 创建解密器
                ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
                // 解密
                using (MemoryStream ms = new MemoryStream(Convert.FromBase64String(cipherText)))
                {
                    using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
                    {
                        using (StreamReader sr = new StreamReader(cs))
                        {
                            return sr.ReadToEnd();
                        }
                    }
                }
            }
        }
        /// <summary>
        /// 将对象转换为 JSON 字符串
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="data"></param>
        /// <returns></returns>
        public static string GetJsonString<T>(T data)
        {
            return JsonConvert.SerializeObject(data, Formatting.Indented);
        }
        /// <summary>
        /// 将 JSON 字符串转换为对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="jsonString"></param>
        /// <returns></returns>
        public static T GetObjectFromJsonString<T>(string jsonString)
        {
            return JsonConvert.DeserializeObject<T>(jsonString, new JsonSerializerSettings
            {
                // 每次 反序列化的时候 覆盖 
                ObjectCreationHandling = ObjectCreationHandling.Replace,
                NullValueHandling = NullValueHandling.Ignore,
            });
        }
        /// <summary>
        /// 将对象保存到 JSON 文件
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <param name="dataPath"></param>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="Exception"></exception>
        public static void SaveObjectToJsonFile<T>(T obj, string dataPath)
        {
            if (obj is null) throw new ArgumentNullException(nameof(obj), "对象不能为空");
            if (string.IsNullOrEmpty(dataPath)) throw new ArgumentNullException(nameof(dataPath), "数据路径不能为空");
            try
            {
                string jsonString = GetJsonString<T>(obj);
                // 保存到指定路径
                File.WriteAllText(dataPath, jsonString);
            }
            catch (Exception ex)
            {
                throw new Exception("保存用户数据失败", ex);
            }
        }
        /// <summary>
        /// 异步将对象保存到 JSON 文件
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <param name="dataPath"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="Exception"></exception>
        public static async Task SaveObjectToJsonFileAsync<T>(T obj, string dataPath)
        {
            if (obj is null) throw new ArgumentNullException(nameof(obj), "对象不能为空");
            if (string.IsNullOrEmpty(dataPath)) throw new ArgumentNullException(nameof(dataPath), "数据路径不能为空");
            try
            {
                string jsonString = GetJsonString<T>(obj);
                // 保存到指定路径
                File.WriteAllTextAsync(dataPath, jsonString).GetAwaiter().GetResult();
            }
            catch (Exception ex)
            {
                throw new Exception("保存用户数据失败", ex);
            }
        }
        /// <summary>
        /// 深Copy
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static T DeepCopy<T>(T obj)
        {
            var json = GetJsonString(obj);
            return GetObjectFromJsonString<T>(json);
        }
    }
}
